package services.common;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import models.common.bean.Endorse;
import models.common.entity.t_commercial_paper_info;
import models.common.entity.t_commercial_paper_info.TicketStatus;
import models.common.entity.t_company_info;
import models.common.entity.t_creditor_right_debt;
import models.common.entity.t_creditor_right_debt.CreditorRightDebtStatus;
import models.common.entity.t_deal_user;
import models.common.entity.t_digital_commercial_paper;
import models.common.entity.t_digital_commercial_paper.DigitalStatus;
import models.common.entity.t_user_credit.AuditResult;
import models.common.entity.t_endorse;
import models.common.entity.t_flow_switch;
import models.common.entity.t_user_credit;
import models.common.entity.t_user_credit_detail;
import models.common.entity.t_user_fund;

import org.apache.commons.lang.StringUtils;

import play.Logger;

import services.base.BaseService;

import common.constants.SettingKey;
import common.enums.NoticeScene;
import common.enums.ServiceType;
import common.utils.DateUtil;
import common.utils.Factory;
import common.utils.FeeCalculateUtil;
import common.utils.ImgUtil;
import common.utils.LoggerUtil;
import common.utils.OrderNoUtil;
import common.utils.PageBean;
import common.utils.ResultInfo;
import common.utils.number.Arith;

import daos.common.EndorseDao;

/**
 * 背书表service
 * 
 * @author xiaojun
 * @version 2017-4-14 下午4:38:41
 */
public class EndorseService extends BaseService<t_endorse> {
	private EndorseDao endorseDao;

	protected EndorseService() {
		endorseDao = Factory.getDao(EndorseDao.class);
		super.basedao = endorseDao;
	}

	protected static CreditorRightDebtService creditorRightDebtService = Factory
			.getService(CreditorRightDebtService.class);

	protected static DigitalCommercialPaperService digitalCommercialPaperService = Factory
			.getService(DigitalCommercialPaperService.class);

	protected static CommerciaPaperiInfoService commerciaPaperiInfoService = Factory
			.getService(CommerciaPaperiInfoService.class);

	protected static FlowSwitchService flowSwitchService = Factory
			.getService(FlowSwitchService.class);
	protected static UserService userService = Factory
			.getService(UserService.class);

	protected static UserCreditService userCreditService = Factory
			.getService(UserCreditService.class);

	/** 注入系统设置service */
	protected static SettingService settingService = Factory
			.getService(SettingService.class);

	protected static DealPlatformService dealPlatformService = Factory
			.getService(DealPlatformService.class);

	protected static NoticeService noticeService = Factory
			.getService(NoticeService.class);

	protected static UserCreditDetailService userCreditDetailService = Factory
			.getService(UserCreditDetailService.class);

	protected static UserFundService userFundService = Factory
			.getService(UserFundService.class);

	protected static DealUserService dealuserservice = Factory
			.getService(DealUserService.class);

	protected static CompanyInfoService companyInfoService = Factory
			.getService(CompanyInfoService.class);

	/**
	 * 更新背书表数据
	 * 
	 * @param t
	 *            背书表实体（t_endorse）
	 * @return
	 * @author xiaojun
	 * @version 2017-5-3 下午7:20:42
	 */
	public boolean saveEndorse(t_endorse t) {
		return endorseDao.save(t);
	}

	/**
	 * 更新数字商票表状态
	 * 
	 * @param t
	 *            数字商票实体
	 * @return
	 * @author xiaojun
	 * @version 2017-5-3 下午7:20:42
	 */

	public boolean updateStatus(int status, int olStatus, long id) {
		return endorseDao.updateStatus(status, olStatus, id);
	}

	/***
	 * 前台- 账户中心- 交易管理-数字商票-开出（收到）的背书
	 * 
	 * @param showType
	 *            状态 0 所有 1 待确认 2 已确认 3 已拒收 4 已到期 5 已逾期 6 已失效 7 已撤销 8 质押中 9 已背书
	 * @param type
	 *            0 开出的背书流转 1 收到的背书流转
	 * @param currPage
	 * @param pageSize
	 * @param exports
	 *            导出
	 * @param user_id
	 *            用户id
	 * @param checkin_time
	 *            开始时间
	 * @param to_checkin_time
	 *            结束时间
	 * @return PageBean<t_endorse>
	 * @author xiaojun
	 * @version 2017-5-16
	 */
	public PageBean<t_endorse> pageOfEndorseList(int showType, int type,
			int currPage, int pageSize, int exports, long user_id,
			String checkin_time, String to_checkin_time) {

		return endorseDao.pageOfEndorseList(showType, type, currPage, pageSize,
				exports, user_id, checkin_time, to_checkin_time);
	}

	/**
	 * 前台- 账户中心- 交易管理-数字商票-开出（收到）的背书-金额计算
	 * 
	 * @param showType
	 *            状态 0 所有 1 待确认 2 已确认 3 已拒收 4 已到期 5 已逾期 6 已失效 7 已撤销 8 质押中 9 已背书
	 * @param type
	 *            0 开出的数字商票 1 收到的数字商票
	 * @param currPage
	 * @param pageSize
	 * @param money
	 *            要计算的金额字段
	 * @param user_id
	 *            用户id
	 * @param checkin_time
	 *            开始时间
	 * @param to_checkin_time
	 *            结束时间
	 * @return
	 * @author xiaojun
	 * @version 2017-5-3 下午7:20:42
	 */
	public double endorseTicketAmount(int showType, int type, String money,
			long user_id, String checkin_time, String to_checkin_time) {

		return endorseDao.endorseTicketAmount(showType, type, money, user_id,
				checkin_time, to_checkin_time);
	}

	/**
	 * 背书申请
	 * 
	 * @param dcp
	 * @param creditorId
	 * @return
	 * @author xiaojun
	 * @version 2017-8-4
	 */
	public ResultInfo endorseApply(t_endorse dcp, long creditorId) {
		ResultInfo result = new ResultInfo();
		// 背书控制开关
		t_flow_switch flowSwitch = flowSwitchService.findByID(1);
		if (flowSwitch.flow_switch == 1) {
			result.code = -1;
			result.msg = "背书功能已关闭！";
			return result;
		}
		t_creditor_right_debt crd = creditorRightDebtService
				.findByID(creditorId);
		if (crd == null) {
			result.code = -1;
			result.msg = "请选择有效债权！";
			return result;
		}
		// 更新债权债务表的剩余额度数据 和状态
		if (crd.rest_debt_money < dcp.bill_money) {
			LoggerUtil.error(true, "债权剩余金额不能小于背书商票金额");
			result.code = -1;
			result.msg = "债权剩余金额不能小于背书商票金额！";
			return result;
		}
		
		//查看对应的商票信息
		t_commercial_paper_info cpi = commerciaPaperiInfoService
				.findByID(dcp.original_id);

		// 增加受让额度
		t_user_credit user_credit = userCreditService
				.findByID(dcp.receive_credit_id);
		
		t_user_credit userCredit = userCreditService.findByUserTransfer(
				crd.company_id, cpi.receive_credit_id, user_credit.credit_granting_code);
		if (userCredit == null) {
			userCredit = new t_user_credit();
			userCredit.time = new Date();
			userCredit.setStatus(AuditResult.TRANSFER);
			userCredit.user_id = crd.company_id;
			userCredit.user_name = crd.creditor_name;
			userCredit.credit_granting_code = userCreditService
					.getGrantingCcode(user_credit.credit_granting_code);
			userCredit.start_time = user_credit.start_time;
			userCredit.end_time = user_credit.end_time;
			userCredit.financing_confine_limit = user_credit.financing_confine_limit;
			userCredit.bond_percent = user_credit.bond_percent;
			userCredit.custodian_fee = user_credit.custodian_fee;
			userCredit.flow_limit = user_credit.flow_limit;
			userCredit.parent_id = cpi.receive_credit_id;
			userCredit.lender_id = user_credit.lender_id;
			userCredit.lender_name = user_credit.lender_name;
		}
		userCredit.transferee_limit += dcp.bill_money;
		userCredit.transferee_used_limit += dcp.bill_money;
		userCredit.usable_limit += dcp.bill_money;
		boolean saveCredit = userCreditService.save(userCredit);
		if (!saveCredit) {
			LoggerUtil.error(false, "更新收票人授信额度异常");
			result.code = -1;
			result.msg = "更新收票人授信额度异常";
			return result;
		}
		// 背书表
		t_endorse endorse = new t_endorse();
		endorse.lender_id = dcp.lender_id;
		endorse.lender_name = dcp.lender_name;
		endorse.finacing_ratio = dcp.finacing_ratio;
		endorse.credit_limit_id = dcp.receive_credit_id;
		endorse.commer_paper_id = dcp.commer_paper_id;

		endorse.endorse_company_id = dcp.endoresd_company_id;
		endorse.endorse_company_name = dcp.endoresd_company_name;
		endorse.contract_name_code = crd.contract_name_code;
		endorse.bill_money = dcp.bill_money;
		endorse.finacing_limit = dcp.finacing_limit;
		endorse.endoresd_company_name = crd.creditor_name;
		if (crd.company_id <= 0) {
			result.code = -1;
			result.msg = "被背书人未在平台注册，无法背书！";
			return result;
		}
		endorse.endoresd_company_id = crd.company_id;
		endorse.endorse_time = new Date();
		endorse.payment_time = dcp.payment_time;
		endorse.paper_pic_on = dcp.paper_pic_on;
		endorse.paper_pic_under = dcp.paper_pic_under;
		endorse.original_id = dcp.original_id;
		endorse.digital_id = dcp.digital_id;// ？
		endorse.debt_creditor_id = crd.id;
		String str = StringUtils.substringBefore(dcp.certificate_code, "-");
		int prefix = Integer.valueOf(str);
		endorse.certificate_code = ++prefix + "-"
				+ StringUtils.substringAfter(dcp.certificate_code, "-");
		
		t_digital_commercial_paper digital_commercial_paper = digitalCommercialPaperService
				.findByID(dcp.digital_id);
		digital_commercial_paper.certificate_code = endorse.certificate_code;
		endorse.paper_pic_on = ImgUtil.screenshot(digital_commercial_paper, 1,
				cpi, null);

		endorse.company_credit_id = dcp.receive_credit_id;
		endorse.receive_credit_id = userCredit.id;
		boolean save = saveEndorse(endorse);
		if (!save) {
			LoggerUtil.error(true, "更新背书表数据异常");
			result.code = -1;
			result.msg = "更新背书表数据异常！";
			return result;
		}
		// 修改债权数据
		crd.rest_debt_money -= dcp.bill_money;
		if (crd.rest_debt_money < 0) {
			LoggerUtil.error(true, "债权剩余金额不能小于背书金额");
			result.code = -1;
			result.msg = "债权剩余金额不能小于背书金额！";
			return result;
		}
		if (crd.rest_debt_money == 0) {
			//crd.status = t_creditor_right_debt.CreditorRightDebtStatus.LOSE_EFFICACY.code;
		}
		boolean saveDebt = creditorRightDebtService.addCreditorRightDebt(crd);
		if (!saveDebt) {
			LoggerUtil.error(true, "更新债权状态异常");
			result.code = -1;
			result.msg = "更新债权状态异常！";
			return result;
		}
		// 修改背书表状态
		save = updateStatus(DigitalStatus.ENDORSE.code,
				DigitalStatus.CONFIRM.code, dcp.id);
		if (!save) {
			LoggerUtil.error(true, "更新背书状态异常");
			result.code = -1;
			result.msg = "更新背书状态异常！";
			return result;
		}
		// 计算背书额度
		result = endorseCredit(endorse, dcp.receive_credit_id, cpi.receive_credit_id);
		if (result.code < 1) {
			LoggerUtil.error(true, "债权剩余金额更新异常");
			return result;
		}
		result.code = 1;
		result.msg = "背书成功！";
		return result;
	}

	/**
	 * 背书额度计算
	 * 
	 * @param endorse
	 * @param endorse_credit_id
	 *            背书人度id
	 * @return
	 * @author xiaojun
	 * @version 2018-1-16
	 */
	public ResultInfo endorseCredit(t_endorse endorse, long endorse_credit_id, long orglId) {
		ResultInfo result = new ResultInfo();
		// 减少背书人授信额度
		t_user_credit user_credit = userCreditService
				.findByID(endorse_credit_id);
		double paper_money = endorse.bill_money;
		if(Arith.sub(user_credit.usable_limit, paper_money) < 0){
			LoggerUtil.error(false, "授信额度不足，不能进行背书");
			result.code = -1;
			result.msg = "授信额度不足，不能进行背书";
			return result;
		}
		user_credit.usable_limit -= paper_money;
		user_credit.transfer_used_limit += paper_money;
		boolean saveCredit = userCreditService.save(user_credit);
		if (!saveCredit) {
			LoggerUtil.error(false, "更新授信额度异常");
			result.code = -1;
			result.msg = "更新授信额度异常";
			return result;
		}
		// 增加明细记录
		String service_order_no = OrderNoUtil.getNormalOrderNo(
				ServiceType.TICKET_AVERT, "");
		t_user_credit_detail amountDetail = new t_user_credit_detail(
				new Date(), endorse.endorse_company_id,
				endorse.endorse_company_name, 0,
				user_credit.credit_granting_code, user_credit.start_time,
				user_credit.end_time, user_credit.lender_id,
				user_credit.lender_name, 0, paper_money, 0, 0, 0,
				-paper_money, service_order_no,
				ServiceType.TICKET_AVERT.value, orglId, 0);
		boolean saveDetail = userCreditDetailService.save(amountDetail);
		if (!saveDetail) {
			LoggerUtil.error(false, "新增开票人额度明细异常");
			result.code = -1;
			result.msg = "新增额度明细异常";
			return result;
		}
		// 增加被背书人授信额度
		t_user_credit userCredit = userCreditService
				.findByID(endorse.receive_credit_id);

		// 增加明细
		service_order_no = OrderNoUtil.getNormalOrderNo(
				ServiceType.TICKET_TRANSFEREE, "");
		amountDetail = new t_user_credit_detail(new Date(),
				endorse.endoresd_company_id, endorse.endoresd_company_name,
				0, userCredit.credit_granting_code,
				user_credit.start_time, user_credit.end_time,
				user_credit.lender_id, user_credit.lender_name, 0, 0,
				paper_money, 0, 0, paper_money, service_order_no,
				ServiceType.TICKET_TRANSFEREE.value, orglId,
				endorse.endorse_company_id);
		saveDetail = userCreditDetailService.save(amountDetail);
		if (!saveDetail) {
			LoggerUtil.error(false, "新增收票人额度明细异常");
			result.code = -1;
			result.msg = "新增额度明细异常";
			return result;
		}
		//获取背书的背书日期
		Date time = new Date();

		//获取背书的到期时间
		Date paperExpireTime = endorse.payment_time;
		
		if(time.compareTo(paperExpireTime)!=-1){
			result.code = -1;
			result.msg = "开票的日期不能大于商票的截止日期";
			return result;
		}
		
		int dateCount = DateUtil.getDaysDiffCeil(time, paperExpireTime);
		
		// 冻结额度流转管理费
		t_user_credit ol_credit = userCreditService
				.findByID(endorse.credit_limit_id);
		/*double custodian_fee = Arith.div(Arith.mul(
				Arith.mul(endorse.bill_money, ol_credit.custodian_fee), dateCount),
				Arith.mul(30, 100), 2);*/
		
		
		
		//TODO
		//票信额度管理费
		double custodian_fee = FeeCalculateUtil.getTransfer(endorse.bill_money, time, paperExpireTime, ol_credit.custodian_fee);
		
		t_user_fund userFund = userFundService
				.queryUserFundByUserId(endorse.endorse_company_id);
		if (userFund.balance < custodian_fee) {
			result.code = -1;
			result.msg = "余额不足缴纳票信额度受让管理服务费！需支付" + custodian_fee +"元";;
			return result;
		}
		if(custodian_fee > 0){
			boolean saveFreeze = userFundService.userFundFreeze(
					endorse.endorse_company_id, custodian_fee);
			if (!saveFreeze) {
				result.code = -1;
				result.msg = "冻结票信额度受让管理服务费异常！";
				return result;
			}
			userFund = userFundService
					.queryUserFundByUserId(endorse.endorse_company_id);
			String serviceOrderNo = OrderNoUtil.getNormalOrderNo(
					ServiceType.USER_UNFREEZE, "");
			/** 添加用户交易记录 */
			Map<String, String> summaryPrams = new HashMap<String, String>();
			summaryPrams.put("amount", custodian_fee + "");
			summaryPrams.put("certificate_code", endorse.certificate_code);
			boolean addDeal = dealuserservice.addDealUserInfo(
					serviceOrderNo, // 订单号
					endorse.endorse_company_id, custodian_fee, userFund.balance,
					userFund.freeze, t_deal_user.OperationType.CUSTODIAN_FEE,
					summaryPrams);
			
			if (!addDeal) {
				result.code = -1;
				result.msg = "添加交易记录失败！";
				return result;
			}
		}

		
		// 票信流转服务费费率
		double fee = Double.valueOf(settingService
				.findSettingValueByKey(SettingKey.CUSTODIAN_FEE));
		
		//票信流转服务费
		double leader_custodian_fee = FeeCalculateUtil.getTransfer(endorse.bill_money,time , paperExpireTime, fee);

		// 收取票信流转服务费,先冻结，如果不是数字商票不需要进行冻结金额
		if ( endorse.lender_id > 0 && leader_custodian_fee > 0) {
			boolean saveFreeze = userFundService.userFundFreeze(endorse.lender_id,
					leader_custodian_fee);
			if (!saveFreeze) {
				result.code = -1;
				result.msg = "冻结票信流转受让服务费失败！";
				return result;
			}
			userFund = userFundService
					.queryUserFundByUserId(endorse.lender_id);
			String serviceOrderNo = OrderNoUtil.getNormalOrderNo(
					ServiceType.TICKET_AVERT, "");
			/** 添加用户交易记录 */
			Map<String, String> summaryPrams = new HashMap<String, String>();
			summaryPrams.put("certificate_code", endorse.certificate_code);
			summaryPrams.put("amount", leader_custodian_fee + "");
			boolean addDeal = dealuserservice.addDealUserInfo(
					serviceOrderNo, // 订单号
					endorse.lender_id, leader_custodian_fee, userFund.balance, userFund.freeze,
					t_deal_user.OperationType.FREEZE_FETCH_PAY_PLAT_CREDIT, summaryPrams);
			
			if (!addDeal) {
				result.code = -1;
				result.msg = "添加交易记录失败！";
				return result;
			}
		}
		
		// 发送通知
		t_company_info company_info = companyInfoService
				.findCompanyInfoByUserId(endorse.endoresd_company_id);
		if (company_info == null) {
			result.code = -1;
			result.msg = "债权剩余金额更新异常";
			return result;
		}
		Map<String, Object> param = new HashMap<String, Object>();
		param.put("user_name", company_info.full_name);
		param.put("drawee", endorse.endorse_company_name);
		noticeService.sendSysNotice(company_info.user_id,
				NoticeScene.ENDORSE_AFFIRM, param);
		result.code = 1;
		result.msg = "背书操作成功！";
		return result;
	}

	/**
	 * 托收
	 * 
	 * @param id
	 * @return
	 * @author xiaojun
	 * @version 2017-8-4
	 */
	public ResultInfo collection(long id) {
		ResultInfo result = new ResultInfo();
		// 业务流水号
		t_endorse endorse = findByID(id);
		if (endorse == null) {
			result.code = -1;
			result.msg = "查询背书信息失败！";
			return result;
		}
		if (endorse.receive_endorse_status != DigitalStatus.EXPIRE.code
				&& endorse.receive_endorse_status != DigitalStatus.OVERDUE.code) {
			result.code = -1;
			result.msg = "状态非法";
			return result;
		}
		
		t_commercial_paper_info cpi = commerciaPaperiInfoService
				.findByID(endorse.commer_paper_id);
		if ( null == cpi) {
			result.code = -1;
			result.msg = "商票信息异常！";
			return result;
		}
		cpi.collection_status = 1;
		cpi = commerciaPaperiInfoService.addTicket(cpi);
		if (cpi == null) {
			result.code = -1;
			result.msg = "商票托收状态更新失败！";
			return result;
		}
		/*olcpi.collection_status = 1;
		olcpi = commerciaPaperiInfoService.addTicket(olcpi);
		if (olcpi == null) {
			result.code = -1;
			result.msg = "商票托收状态更新失败！";
			return result;
		}*/
		// 发送通知
		t_company_info company_info = companyInfoService
				.findByUserId(endorse.lender_id);
		if (company_info == null) {
			result.code = -1;
			result.msg = "债权剩余金额更新异常";
			return result;
		}
		Map<String, Object> param = new HashMap<String, Object>();
		param.put("user_name", company_info.full_name);
		param.put("bill_code", endorse.certificate_code + "背书");
		noticeService.sendSysNotice(company_info.user_id,
				NoticeScene.COLLECTION_AFFIRM, param);
		result.code = 2;
		result.msg = "托收成功！";
		return result;
	}

	/**
	 * 确认划款
	 * 
	 * @param id
	 *            数字商票id
	 * @param user_id
	 *            用户id
	 * @return
	 * @author xiaojun
	 * @version 2017-8-3
	 */
	public ResultInfo confirmTransfer(long id, long user_id) {
		ResultInfo result = new ResultInfo();
		t_endorse endorse = findByID(id);
		if (endorse == null) {
			result.code = -1;
			result.msg = "查询背书信息失败！";
			return result;
		}
		if (user_id != endorse.endoresd_company_id) {
			result.code = -1;
			result.msg = "警告！不是收票人不能操作！";
			return result;
		}
		if (endorse.receive_endorse_status != DigitalStatus.REPAYMENT.code) {
			result.code = -1;
			result.msg = "状态非法！";
			return result;
		}

		t_commercial_paper_info cpi = commerciaPaperiInfoService
				.findByID(endorse.commer_paper_id);
		if (null == cpi) {
			result.code = -1;
			result.msg = "商票信息异常！";
			return result;
		}
		int i = commerciaPaperiInfoService.upPaperStatus(
				TicketStatus.ALL_SQUARED.code, 0, cpi.id);
		if (i < 0) {
			result.code = -1;
			result.msg = "商票状态更新失败！";
			return result;
		}
		boolean upStatus = updateStatus(DigitalStatus.LOSE_EFFICACY.code,
				DigitalStatus.REPAYMENT.code, id);
		if (!upStatus) {
			result.code = -1;
			result.msg = "数字商票状态更新失败！";
			return result;
		}
//		t_digital_commercial_paper dcp = digitalCommercialPaperService
//				.findByID(endorse.digital_id);
		// 开票人额度
//		t_user_credit user_credit = userCreditService
//				.findByID(dcp.company_credit_id);
//		user_credit.cleared_limit = dcp.digital_com_paper_money;
//
//		if (user_credit.id != dcp.credit_limit_id) {
//			user_credit.transferee_limit += dcp.digital_com_paper_money;
//		}
//		user_credit.usable_limit += dcp.digital_com_paper_money;
//		boolean save = userCreditService.save(user_credit);
//		if (!save) {
//			result.code = -1;
//			result.msg = "开票人额度更新失败！";
//			return result;
//		}
		// 收票人额度变化
//		t_user_credit userCredit = userCreditService
//				.findByID(endorse.receive_credit_id);
//		userCredit.usable_limit -= endorse.bill_money;
//		userCredit.cleared_limit += endorse.bill_money;
//		boolean save  = userCreditService.save(userCredit);
//		if (!save) {
//			result.code = -1;
//			result.msg = "收票人额度更新失败！";
//			return result;
//		}
		// 添加开票人额度明细表信息
//		String service_order_no = OrderNoUtil.getNormalOrderNo(
//				ServiceType.TICKET_CASH, "");
//		t_user_credit_detail amountDetail = new t_user_credit_detail(
//				new Date(), dcp.company_id, dcp.drawer,
//				dcp.digital_com_paper_money, user_credit.credit_granting_code,
//				user_credit.start_time, user_credit.end_time,
//				user_credit.lender_id, user_credit.lender_name, 0, 0, 0,
//				dcp.digital_com_paper_money, 0, user_credit.usable_limit,
//				service_order_no, ServiceType.TICKET_CASH.value,
//				cpi.receive_credit_id, endorse.endoresd_company_id);
//		boolean saveDetail = userCreditDetailService.save(amountDetail);
//		if (!saveDetail) {
//			LoggerUtil.error(false, "新增开票人额度明细异常");
//			result.code = -1;
//			result.msg = "新增额度明细异常";
//			return result;
//		}
		// 添加收票人额度明细表信息
//		String service_order_no = OrderNoUtil.getNormalOrderNo(
//				ServiceType.COLLECTION_SUCCESS, "");
//		t_user_credit_detail amountDetail = new t_user_credit_detail(new Date(),
//				endorse.endoresd_company_id, endorse.endoresd_company_name,
//				0, userCredit.credit_granting_code,
//				userCredit.start_time, userCredit.end_time,
//				userCredit.lender_id, userCredit.lender_name, 0, 0, 0,
//				dcp.digital_com_paper_money, 0, -dcp.digital_com_paper_money,
//				service_order_no, ServiceType.COLLECTION_SUCCESS.value,
//				cpi.receive_credit_id, 0);
//		boolean saveDetail = userCreditDetailService.save(amountDetail);
//		if (!saveDetail) {
//			LoggerUtil.error(false, "新增收票人额度明细异常");
//			result.code = -1;
//			result.msg = "新增额度明细异常";
//			return result;
//		}
		// 发送通知
		
		  t_company_info company_info = companyInfoService.findByID(endorse.lender_id); 
		  if(company_info == null){
			  result.code = -1;
			  result.msg = "获取放款人信息失败"; 
			  return result; 
		  }
		  Map<String, Object> param = new HashMap<String, Object>();
		  param.put("user_name",company_info.full_name);
		  param.put("full_name",endorse.endoresd_company_name);
		  param.put("bill_code",cpi.bill_code);
		  noticeService.sendSysNotice(company_info.user_id,  NoticeScene.CONFIRM_TRANSFER, param);
		 
		result.code = 1;
		result.msg = "确认成功！";
		return result;

	}

	/**
	 * 定时任务 标记背书流转到期
	 * 
	 * @return
	 * @author xiaojun
	 * @version 2017-5-24
	 */
	public ResultInfo systemMarkEndorseTicketExpire() {
		ResultInfo result = new ResultInfo();
		// 将到期的待签收背书流转强制撤回
		result = autocancelEndorse();
		if (result.code < 0) {
			return result;
		}
//		// 将到期的待签收数字凭证强制撤回
//		result = digitalCommercialPaperService.autocancelDigital();
//		if (result.code < 0) {
//			return result;
//		}
		return endorseDao.autoMarkEndorseTicketExpire();
	}

	/**
	 * 定时任务 标记背书流转逾期
	 * 
	 * @return
	 * @author xiaojun
	 * @version 2017-5-24
	 */
	public ResultInfo systemMarkEndorseTicketOverdue() {
		return endorseDao.autoMarkEndorseTicketOverdue();
	}

	/**
	 * 撤回/拒收 背书流转
	 * 
	 * @param id
	 *            背书表id
	 * @param type
	 *            0 已撤票 1 已拒收
	 * @return
	 * @author xiaojun
	 * @version 2017-6-29
	 */
	public ResultInfo cancelEndorse(long id, int type) {
		ResultInfo result = new ResultInfo();
		// 获取背书表信息
		t_endorse endorse = findByID(id);
		if (endorse == null) {
			result.code = -1;
			result.msg = "数据异常";
			return result;
		}
		t_digital_commercial_paper dcp = digitalCommercialPaperService
				.findByID(endorse.digital_id);
		t_commercial_paper_info com = commerciaPaperiInfoService
				.findByID(dcp.commer_paper_id);
		t_creditor_right_debt crd = creditorRightDebtService
				.findByID(endorse.debt_creditor_id);
		if (endorse.receive_endorse_status != DigitalStatus.TBC.code) {
			result.code = -1;
			result.msg = "状态非法！";
			return result;
		}
		// 更新债权债务表的剩余额度数据
		crd.rest_debt_money += dcp.digital_com_paper_money;
		crd.status = t_creditor_right_debt.CreditorRightDebtStatus.CONFIRM.code;
		boolean save = creditorRightDebtService.addCreditorRightDebt(crd);
		if (!save) {
			result.code = -1;
			result.msg = "债权剩余金额更新异常";
			return result;
		}
		String str = StringUtils.substringBefore(endorse.certificate_code, "-");
		int prefix = Integer.valueOf(str);
		String certificate_code = --prefix + "-"
				+ StringUtils.substringAfter(endorse.certificate_code, "-");
		if (prefix >= 2) {
			t_endorse endorse2 = findByColumn(
					" certificate_code = ? AND receive_endorse_status = ?",
					certificate_code, DigitalStatus.ENDORSE.code);
			endorse2.receive_endorse_status = DigitalStatus.CONFIRM.code;
			save = saveEndorse(endorse2);
			if (!save) {
				LoggerUtil.error(true, "背书表数据异常");
				result.code = -1;
				result.msg = "背书表数据异常";
				return result;
			}
		} else {
			// 修改数字商票状态为已确认
			dcp.digital_com_status = t_digital_commercial_paper.DigitalStatus.CONFIRM.code;
			dcp.is_endorse = 0;
			dcp = digitalCommercialPaperService.saveDigitalPapre(dcp);
			if (dcp == null) {
				result.code = -1;
				result.msg = "更新数字商票状态异常";
				return result;
			}
		}
		// 修改背书表状态
		if (type == 0) {
			endorse.receive_endorse_status = DigitalStatus.REVOCATION.code;
		} else if (type == 1) {
			endorse.receive_endorse_status = DigitalStatus.REJECTION.code;
		}
		save = saveEndorse(endorse);
		if (!save) {
			LoggerUtil.error(true, "背书表数据异常");
			result.code = -1;
			result.msg = "背书表数据异常";
			return result;
		}
		// =======================

		// 更新背书人额度信息
		t_user_credit user_credit = userCreditService
				.findByID(endorse.company_credit_id);
		double paper_money = endorse.bill_money;
		user_credit.usable_limit += paper_money;
		user_credit.transfer_used_limit -= paper_money;
		boolean saveCredit = userCreditService.save(user_credit);
		if (!saveCredit) {
			LoggerUtil.error(false, "更新授信额度异常");
			result.code = -1;
			result.msg = "更新授信额度异常";
			return result;
		}
		// 减少被背书受让额度
		t_user_credit userCredit = userCreditService
				.findByID(endorse.receive_credit_id);
		if (userCredit == null) {
			LoggerUtil.error(false, "更新商票额度异常");
			result.code = -1;
			result.msg = "受让人额度信息异常";
			return result;
		}
		userCredit.transferee_limit -= paper_money;
		userCredit.transferee_used_limit -= paper_money;
		if(Arith.sub(userCredit.usable_limit, paper_money) < 0){
			LoggerUtil.error(false, "授信额度不足，不能进行拒收退回");
			result.code = -1;
			result.msg = "授信额度不足，不能进行拒收退回";
			return result;
		}
		userCredit.usable_limit -= paper_money;
		
		saveCredit = userCreditService.save(userCredit);
		if (!saveCredit) {
			LoggerUtil.error(false, "更新授信额度异常");
			result.code = -1;
			result.msg = "更新授信额度异常";
			return result;
		}
		// 添加出票人额度明细表信息
		String service_order_no = OrderNoUtil.getNormalOrderNo(
				ServiceType.TICKET_AVERT, "");
		t_user_credit_detail amountDetail = new t_user_credit_detail(
				new Date(), endorse.endorse_company_id,
				endorse.endorse_company_name, 0,
				user_credit.credit_granting_code, user_credit.start_time,
				user_credit.end_time, user_credit.lender_id,
				user_credit.lender_name, 0, -paper_money, 0, 0, 0,
				paper_money, service_order_no,
				ServiceType.CREDIT_BACK.value, com.receive_credit_id,
				0);
		boolean saveDetail = userCreditDetailService.save(amountDetail);
		if (!saveDetail) {
			LoggerUtil.error(false, "新增开票人额度明细异常");
			result.code = -1;
			result.msg = "新增额度明细异常";
			return result;
		}
		// 添加收票人额度明细表信息
		service_order_no = OrderNoUtil.getNormalOrderNo(
				ServiceType.TICKET_TRANSFEREE, "");
		amountDetail = new t_user_credit_detail(new Date(),
				endorse.endoresd_company_id, endorse.endoresd_company_name,
				0, userCredit.credit_granting_code,
				user_credit.start_time, user_credit.end_time,
				user_credit.lender_id, user_credit.lender_name, 0, 0,
				-paper_money, 0, 0, -paper_money, service_order_no,
				ServiceType.CREDIT_BACK.value, com.receive_credit_id,
				endorse.endorse_company_id);
		saveDetail = userCreditDetailService.save(amountDetail);
		if (!saveDetail) {
			LoggerUtil.error(false, "新增收票人额度明细异常");
			result.code = -1;
			result.msg = "新增额度明细异常";
			return result;
		}
		
		// 背书的背书时间
		Date time = endorse.endorse_time;

		// 背书的到期时间
		Date paperExpireTime = endorse.payment_time;
		
		if(time.compareTo(paperExpireTime)!=-1){
			result.code = -1;
			result.msg = "开票的日期不能大于商票的截止日期";
			return result;
		}
		
		int dateCount = DateUtil.getDaysDiffCeil(time, paperExpireTime);
		
		
		/*double custodian_fee = Arith.div(Arith.mul(
				Arith.mul(paper_money, ol_credit.custodian_fee), dateCount),
				Arith.mul(30, 100), 2);*/

		double custodian_fee = FeeCalculateUtil.getTransfer(endorse.bill_money, time, paperExpireTime, user_credit.custodian_fee);
		
		if (custodian_fee > 0) {
			// 解冻票信额度管理费
			boolean saveFreeze = userFundService.userFundUnFreeze(
					endorse.endorse_company_id, custodian_fee);
			if (!saveFreeze) {
				result.code = -1;
				result.msg = "解冻票信额度管理费失败";
				return result;
			}
			t_user_fund userFund = userFundService
					.queryUserFundByUserId(endorse.endorse_company_id);
			String serviceOrderNo = OrderNoUtil.getNormalOrderNo(
					ServiceType.USER_UNFREEZE, "");
			/** 添加用户交易记录 */
			Map<String, String> summaryPrams = new HashMap<String, String>();
			summaryPrams.put("amount", custodian_fee + "");
			summaryPrams.put("certificate_code", endorse.certificate_code);
			boolean addDeal = dealuserservice.addDealUserInfo(
					serviceOrderNo, // 订单号
					endorse.endorse_company_id, custodian_fee, userFund.balance,
					userFund.freeze,
					t_deal_user.OperationType.CUSTODIAN_FEE_UNFREEZE, summaryPrams);
	
			if (!addDeal) {
				result.code = -1;
				result.msg = "添加交易记录失败！";
				return result;
			}
		}
		
		
		// 票信流转服务费费率
		double fee = Double.valueOf(settingService
				.findSettingValueByKey(SettingKey.CUSTODIAN_FEE));
		
		//票信流转服务费
		double leader_custodian_fee = FeeCalculateUtil.getTransfer(endorse.bill_money,time , paperExpireTime, fee);

		// 收取票信流转服务费,先冻结，如果不是数字商票不需要进行冻结金额
		if ( endorse.lender_id > 0 && leader_custodian_fee > 0) {
			boolean saveFreeze = userFundService.userFundUnFreeze(endorse.lender_id,
					leader_custodian_fee);
			if (!saveFreeze) {
				result.code = -1;
				result.msg = "冻结票信流转服务费失败！";
				return result;
			}
			t_user_fund userFund = userFundService
					.queryUserFundByUserId(endorse.lender_id);
			String serviceOrderNo = OrderNoUtil.getNormalOrderNo(
					ServiceType.TICKET_AVERT, "");
			/** 添加用户交易记录 */
			Map<String, String> summaryPrams = new HashMap<String, String>();
			summaryPrams.put("certificate_code", endorse.certificate_code);
			summaryPrams.put("amount", leader_custodian_fee + "");
			boolean addDeal = dealuserservice.addDealUserInfo(
					serviceOrderNo, // 订单号
					endorse.lender_id, leader_custodian_fee, userFund.balance, userFund.freeze,
					t_deal_user.OperationType.UNFREEZE_FETCH_PAY_PLAT_CREDIT, summaryPrams);
			
			if (!addDeal) {
				result.code = -1;
				result.msg = "添加交易记录失败！";
				return result;
			}
		}
		
		t_company_info company_info = null;
		if (type == 0) {
			company_info = companyInfoService
					.findByUserId(endorse.endoresd_company_id);
		} else {
			company_info = companyInfoService
					.findByUserId(endorse.endorse_company_id);
		}
		if (company_info == null) {
			result.code = -1;
			result.msg = "企业信息异常";
			return result;
		}
		// 发送通知
		Map<String, Object> param = new HashMap<String, Object>();
		param.put("user_name", company_info.full_name);
		param.put("drawee", endorse.endorse_company_name);
		param.put("certificate_code", endorse.certificate_code);
		param.put("status", endorse.getStatus().value);
		noticeService.sendSysNotice(company_info.user_id,
				NoticeScene.ENDORSE_AFFIRM_NO, param);
		result.code = 1;
		result.msg = "操作成功！ 状态更新为：" + endorse.getStatus().value;
		return result;
	}

	/**
	 * 交易管理-商票列表-背书流转列表-(确认签收)
	 * 
	 * @param id
	 * @return
	 * @author xiaojun
	 * @version 2017-8-4
	 */
	public ResultInfo confirmEndorseTicket(long id, long user_id) {
		ResultInfo result = new ResultInfo();
		// 获取背书表信息
		t_endorse endorse = findByID(id);
		if (endorse == null) {
			result.code = -1;
			result.msg = "数据异常";
			return result;
		}
		if (user_id != endorse.endoresd_company_id) {
			result.code = -1;
			result.msg = "警告！操作非法";
			return result;
		}
		t_digital_commercial_paper dcp = digitalCommercialPaperService
				.findByID(endorse.digital_id);
		t_commercial_paper_info cpi = commerciaPaperiInfoService
				.findByID(endorse.original_id);
		if (endorse.receive_endorse_status != DigitalStatus.TBC.code) {
			result.code = -1;
			result.msg = "状态非法！";
			return result;
		}

		// 更新背书表状态为 已确认
		endorse.receive_endorse_status = DigitalStatus.CONFIRM.code;
		dcp.certificate_code = endorse.certificate_code;
		endorse.paper_pic_under = ImgUtil.screenshot(dcp, 6, cpi, endorse);
		endorse.endorse_time = new Date();
		boolean save = saveEndorse(endorse);
		if (!save) {
			LoggerUtil.error(true, "背书表数据异常");
			result.code = -1;
			result.msg = "背书表数据异常";
			return result;
		}
		// 更新商票的持票人
		cpi.receive_id = endorse.endoresd_company_id;
		cpi.certificate_code = endorse.certificate_code;
		cpi.paper_pic_on = endorse.paper_pic_on;
		cpi.paper_pic_under = endorse.paper_pic_under;

		cpi.is_endorse = 1;// 1标识已背书
		cpi.circulation_id = endorse.id;
		cpi.credit_limit_id = endorse.receive_credit_id;
		cpi = commerciaPaperiInfoService.addTicket(cpi);
		if (cpi == null) {
			LoggerUtil.error(true, "商票数据异常");
			result.code = -1;
			result.msg = "商票数据异常";
			return result;
		}
		t_user_credit user_credit = userCreditService
				.findByID(endorse.credit_limit_id);

		// 获取商票的信息
		t_commercial_paper_info orgcpi = commerciaPaperiInfoService
				.findByID(dcp.original_id);

		// 商票类型
		int isDigital = 1;
		if(orgcpi != null){
			isDigital =  orgcpi.is_digital;
		}

		// 商票到期日期
		Date paperExpireTime = endorse.payment_time;

		// 登记时间
		Date time = endorse.endorse_time;

		if(time.compareTo(paperExpireTime)!=-1){
			result.code = -1;
			result.msg = "开票的日期不能大于商票的截止日期";
			return result;
		}
		
		// 两个日期相隔的天数
		int dateCount = DateUtil.getDaysDiffCeil(time, paperExpireTime);
/*
		double custodian_fee = Arith.div(Arith.mul(
				Arith.mul(endorse.bill_money, user_credit.custodian_fee),
				dateCount), Arith.mul(30, 100), 2);
*/

		double custodian_fee = FeeCalculateUtil.getTransfer(endorse.bill_money, time, paperExpireTime, user_credit.custodian_fee);
		
		// 计算费用
		result = digitalCommercialPaperService.userTransaction(
				endorse.endorse_company_id, endorse.lender_id, custodian_fee,
				endorse.certificate_code, dateCount);
		if (result.code < 0) {
			LoggerUtil.error(true, result.msg);
			return result;
		}
		
		//收取票信流转服务费
		//TODO
		// 票信流转服务费费率
		double fee = Double.valueOf(settingService
				.findSettingValueByKey(SettingKey.CUSTODIAN_FEE));
		
		//票信流转服务费
		double leader_custodian_fee = FeeCalculateUtil.getTransfer(endorse.bill_money,time , paperExpireTime, fee);

		// 收取票信流转服务费，如果不是数字商票不需要进行收取lenderTransaction
		result = digitalCommercialPaperService.lenderTransaction(endorse.lender_id,leader_custodian_fee, endorse.certificate_code, dateCount);
		if (result.code < 0) {
			LoggerUtil.error(true, result.msg);
			return result;
		}
		
		
		t_company_info company_info_com = null;
		t_company_info company_info_recei = null;
		company_info_com = companyInfoService
				.findByUserId(endorse.endorse_company_id);
		company_info_recei = companyInfoService
				.findByUserId(endorse.endoresd_company_id);
		if (company_info_com == null) {
			result.code = -1;
			result.msg = "背书企业信息异常";
			return result;
		}
		if (company_info_recei == null) {
			result.code = -1;
			result.msg = "被背书企业信息异常";
			return result;
		}
		// 发送通知
		Map<String, Object> param = new HashMap<String, Object>();
		param.put("user_name", company_info_recei.full_name);
		param.put("drawee", company_info_com.full_name);
		param.put("certificate_code", endorse.certificate_code);
		noticeService.sendSysNotice(company_info_com.user_id,
				NoticeScene.ENDORSE_AFFIRM_OK, param);
		
		result.code = 1;
		result.msg = "操作成功！ 状态跟新为：" + endorse.getStatus().value;
		return result;
	}

	/**
	 * 将到期的待签收背书流转强制撤回
	 * 
	 * @return
	 * @author xiaojun
	 * @version 2017-6-29
	 */

	public ResultInfo autocancelEndorse() {
		ResultInfo result = new ResultInfo();
		List<t_endorse> endorseList = endorseDao.autocancelEndorse();
		if (endorseList != null && endorseList.size() > 0) {
			for (int i = 0; i < endorseList.size(); i++) {
				t_endorse endorse = endorseList.get(i);
				result = cancelEndorse(endorse.id, 0);
				if (result.code < 0) {
					return result;
				}
			}
		}
		return result;

	}

	// //-----------------------------------------------------start-------------------------------------
	/**
	 * 更新背书的额度信息
	 * 
	 * @param amount
	 *            额度
	 * @param id
	 *            id
	 * @return
	 * @author liaijun
	 * @version 2018年1月19日
	 * @param status 
	 */
	public int updateEndors(double amount, long id) {
		return endorseDao.updateEndors(amount, id);
	}
	/**
	 * 融通失效后更新背书的额度信息
	 * 
	 * @param amount
	 *            额度
	 * @param id
	 *            id
	 * @return
	 * @author liaijun
	 * @version 2018年1月19日
	 * @param status 
	 */
	public int updateEndors(double amount, long id, int status) {
		return endorseDao.updateEndors(amount, id,status);
	}
	
	/**
 	 * 查询背书流转记录
 	 *
 	 * @return
 	 * @author fanghanyong
 	 *@version 2018-2-22
 	 */
 	public List<Endorse> endorseRecord(long commer_paper_id){
		return endorseDao.endorseRecord(commer_paper_id);
 	}
}
